package us.kg.kotoriforest.spring.aop.proxy;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;

import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Objects;

/**
 * @author Kotori rotroutine@163.com
 * @since 2025/1/27
 */
/*
    动态代理要求目标对象必须实现接口，因为动态代理是基于接口的
    动态代理出的对象只能强转为接口类型，不能强转为目标对象类型
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class DynamicProxyFactory {
    public static Object getProxy(Object target) {
        Objects.requireNonNull(target, "target is required");

        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                (proxy, method, args) -> {
                    Object result = null;
                    try {
                        System.out.println("[方法准备开始调用] 方法名：" + method.getName() + " 参数：" + Arrays.toString(args));
                        result = method.invoke(target, args);
                        System.out.println("[方法调用结束] 方法名：" + method.getName() + " 结果：" + result);
                    } catch (Exception e) {
                        System.out.println("[方法调用异常] 方法名：" + method.getName() + " 异常：" + e.getCause());
                    } finally {
                        System.out.println("[方法动态代理结束] 方法名：" + method.getName() + " 结果：" + result);
                    }

                    return result;
                }
        );
    }
}
